package com.cloud.gatewaySpringSecurity.filter;

import com.cloud.gatewaySpringSecurity.constant.TokenConstant;
import com.cloud.gatewaySpringSecurity.pojo.Payload;
import com.cloud.gatewaySpringSecurity.pojo.TokenUser;
import com.cloud.gatewaySpringSecurity.properties.RsaKeyProperties;
import com.cloud.gatewaySpringSecurity.service.RedisService;
import com.cloud.gatewaySpringSecurity.utils.JwtUtil;
import com.cloud.gatewaySpringSecurity.utils.SaveMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

/**
 * @author zhozixiong
 * @date 2023/03/03
 */
public class JwtWebFilter implements WebFilter {

    private RsaKeyProperties rsaKeyProperties;
    private RedisService redisService;

    private String[] loginUrls;
    private String[] unnecessaryUrls;

    public JwtWebFilter(RsaKeyProperties rsaKeyProperties, RedisService redisService, String[] loginUrls, String[] unnecessaryUrls) {
        this.rsaKeyProperties = rsaKeyProperties;
        this.redisService = redisService;
        this.loginUrls = loginUrls;
        this.unnecessaryUrls = unnecessaryUrls;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) {
        ServerHttpRequest request = serverWebExchange.getRequest();
        ServerHttpResponse response = serverWebExchange.getResponse();
        //请求类型
        HttpMethod method = request.getMethod();
        //请求路径
        String path = request.getPath().value();
        for(String url : unnecessaryUrls) {
            if(url.equals(path)) {
                return webFilterChain.filter(serverWebExchange);
            }
        }
        String message = judge(request);
        for (String url : loginUrls) {
            if (url.equals(path) && HttpMethod.POST.equals(method)) {
                //防止重复登录
                if(message != null) {
                    return webFilterChain.filter(serverWebExchange);
                }else {
                    return SaveMessage.save(response, HttpStatus.OK, "已登录");
                }
            }
        }
        if (message != null) {
            return SaveMessage.save(response, HttpStatus.BAD_REQUEST, message);
        }
        //放行
        return webFilterChain.filter(serverWebExchange);
    }

    private String judge(ServerHttpRequest request) {
        String token = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
        if(token == null || !token.startsWith(TokenConstant.TOKEN_PREFIX)) {
            return "未登录";
        }
        token = token.replace(TokenConstant.TOKEN_PREFIX, "");
        Payload<TokenUser> payload = JwtUtil.getInfoFromToken(token, rsaKeyProperties.getPublicKey(), TokenUser.class);
        if(payload == null || redisService.getObject(TokenConstant.TOKEN_REDIS_PREFIX + payload.getId()) == null) {
            return "token已过期";
        }
        return null;
    }
}
